#ifndef _THREAD_SAFE_QUEUE_H_
#define _THREAD_SAFE_QUEUE_H_
#include <queue>
#include <mutex>
#include <condition_variable>
template<typename T>
class ThreadSafeQueue
{
private:
    std::queue<T> data;
    std::mutex mutex;
    std::condition_variable cv;
public:
    ThreadSafeQueue() {}

    void push(T item)
    {
        std::unique_lock<std::mutex> lock(mutex);
        data.push(item);
        lock.unlock();
        cv.notify_one();
    }

    bool try_pop(T& item)
    {
        std::unique_lock<std::mutex> lock(mutex);
        if (data.empty())
        {
            return false;
        }
        item = data.front();
        data.pop();
        return true;
    }

    void wait_and_pop(T& item)
    {
        std::unique_lock<std::mutex> lock(mutex);
        while (data.empty())
        {
            cv.wait(lock);
        }
        item = data.front();
        data.pop();
    }

    bool empty() const
    {
        std::unique_lock<std::mutex> lock(mutex);
        return data.empty();
    }
};

#endif // !


